import copy
import time

from PyQt5.QtCore import QThread, pyqtSignal

import var
from utils.RunBack import Run_FCFS, Run_SSTF, Run_SCAN, Run_CSCAN, Run_Caculate


class SCANWorker(QThread):
    draw_label_signal = pyqtSignal(list)

    output_signal = pyqtSignal(str)

    def __init__(self, mission, count, direction):
        super(SCANWorker, self).__init__()
        self.page_requests = mission.copy()
        self.count = count
        self.direction = direction
        fcfs_time = Run_Caculate(Run_FCFS(mission.copy(), var.next_id, var.max_id, var.direct))
        sstf_time = Run_Caculate(Run_SSTF(mission.copy(), var.next_id, var.max_id, var.direct))
        scan_time = Run_Caculate(Run_SCAN(mission.copy(), var.next_id, var.max_id, var.direct))
        cscan_time = Run_Caculate(Run_CSCAN(mission.copy(), var.next_id, var.max_id, var.direct))
        self.all_put = f"FCFS的平均寻道时间{fcfs_time}\n"
        self.all_put += f"SSTF的平均寻道时间{sstf_time}\n"
        self.all_put += f"SCAN的平均寻道时间{scan_time}\n"
        self.all_put += f"CSCAN的平均寻道时间{cscan_time}\n"

    def generateOut(self, queue):
        out_str = "方法: SCAN\n"
        out_str += f"方向{self.direction}\n"
        out_str += f"访问的磁道序列为:\n{queue}\n"
        sum_gap = sum([(abs(queue[i] - queue[i - 1])) for i in range(1, len(queue))])
        out_str += f'移动的磁道数为：{sum_gap}\n'
        out_str += f'平均移动的磁道数为：{sum_gap / self.count}'
        return out_str

    def run(self):
        print("receive run")
        queue_SCAN = []
        TRACK_START = var.next_id
        queue_SCAN.append(TRACK_START)
        track_request_copy = copy.deepcopy(self.page_requests)
        track_request_copy.sort()
        while track_request_copy.__len__() != 0:
            if self.direction == 1:
                for track in track_request_copy.copy():
                    if TRACK_START <= track:
                        queue_SCAN.append(track)
                        track_request_copy.remove(track)
                self.direction = 0

            if self.direction == 0:
                track_request_copy.reverse()
                for track in track_request_copy.copy():
                    if TRACK_START >= track:
                        queue_SCAN.append(track)
                        track_request_copy.remove(track)
                self.direction = 1
        out_put = []
        for val in queue_SCAN:
            out_put.append(val)
            self.draw_label_signal.emit(out_put)
            time.sleep(var.time_split)
        out_put = self.generateOut(queue_SCAN)
        out_put += "\n" + self.all_put
        self.output_signal.emit(out_put)
        print("finish")
